package com.fanketly.musicdiary.test

import android.util.Log
import androidx.activity.compose.BackHandler
import androidx.compose.animation.*
import androidx.compose.animation.core.*
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.*
import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
import com.fanketly.musicdiary.data.TAG
import com.fanketly.musicdiary.ui.components.*
import com.fanketly.musicdiary.ui.theme.*
import kotlinx.coroutines.launch

/**
 * 重组是指在输入更改时再次调用可组合函数的过程。当函数的输入更改时，会发生这种情况。
 * 当 Compose 根据新输入重组时，它仅调用可能已更改的函数或 lambda，
 * 而跳过其余函数或 lambda。通过跳过所有未更改参数的函数或 lambda，Compose 可以高效地重组。
 * 每个可组合函数和 lambda 都可以自行重组
 * 只有非inline函数 才有资格成为重组的最小范围,内联函数，顾名思义，就是在编译时将作为函数参数的函数体直接映射到函数调用处
 **/
@OptIn(
    ExperimentalMaterialApi::class, ExperimentalLifecycleComposeApi::class,
    ExperimentalFoundationApi::class, ExperimentalAnimationApi::class
)
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
//    TestContent()
//    TestContent2()
//    TestContent3()

//    val header = remember {
//        mutableStateOf("A")
//    }
//    val list = remember {
//        mutableStateOf(listOf("A", "B", "C"))
//    }
//    NamePicker(header.value, list.value, { header.value = it }) {//title 更新时 list重组；list更新时，title没有重组
//        list.value = list.value + it
//    }
//    NamePicker()//各更新各的 歪理古德
//    BottomSheet()
//    Foo()
    TestTheme {
    }
}






@Composable
private fun Foo() {
    var text by remember { mutableStateOf("") }
    Button(onClick = { text = "$text $text" }) {
        Log.d(TAG, "Button content lambda")
        Wrapper {
            Text(text).also { Log.d(TAG, "Text") }
        }
    }
}

@Composable
private fun Wrapper(content: @Composable () -> Unit) {
    Log.d(TAG, "Wrapper recomposing")
    Box {
        Log.d(TAG, "Box")
        content()
    }
}


@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun BottomSheet() {
    val coroutineScope = rememberCoroutineScope()
    val sheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)

    BackHandler(sheetState.isVisible) {
        coroutineScope.launch {
            sheetState.hide()
        }
    }
    SheetLayout(sheetState = sheetState)
    SheetItem(sheetState)
//    Text(text = "dasdasd3$sheetState",Modifier.clickable { coroutineScope.launch { sheetState.show() } })
    ModalBottomSheetLayout(sheetState = sheetState, sheetContent = {

        ChooseOrTakePhotoSheet(textColor = TextWhite, {
            coroutineScope.launch {
                sheetState.hide()
            }
        }, {})
    }) {

//        Text(text = "sdsad", Modifier.clickable { coroutineScope.launch { sheetState.show() } })
        Text(text = "sdsad")
    }
}

@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun SheetItem(sheetState: ModalBottomSheetState) {
    val coroutineScope = rememberCoroutineScope()
    Box {

        Text(
            text = "dasdasd3$sheetState",
//            Modifier.clickable { coroutineScope.launch { sheetState.show() } }
        )
    }
}

@OptIn(ExperimentalMaterialApi::class)
@Composable
fun SheetLayout(sheetState: ModalBottomSheetState) {
    val coroutineScope = rememberCoroutineScope()
    Text(text = "dasdasd")
    ModalBottomSheetLayout(sheetState = sheetState, sheetContent = {
        ChooseOrTakePhotoSheet(textColor = TextWhite, {
            coroutineScope.launch {
                sheetState.hide()
            }
        }, {})
    }) {
//        Text(text = "sdsad", Modifier.clickable { coroutineScope.launch { sheetState.show() } })
    }
    Text(text = "dasdasd2", Modifier.clickable { coroutineScope.launch { sheetState.show() } })
}


/**
 * Display a list of names the user can click with a header
 */
@Composable
private fun NamePicker(
//    header: String,
//    names: List<String>,
//    onNameClicked: (String) -> Unit,
//    onDoubleClicked: (String) -> Unit
) {
    val header = remember {
        mutableStateOf("A")
    }
    val list = remember {
        mutableStateOf(listOf("A", "B", "C"))
    }
    val a = header.value
    Column {
        // this will recompose when [header] changes, but not when [names] changes

//        Text(
//            header,
//            style = MaterialTheme.typography.h5,
//            modifier = Modifier.clickable(onClick = { onNameClicked(header + 1) })
//        )
        LazyColumn {
            items(list.value) { name ->
                // When an item's [name] updates, the adapter for that item
                // will recompose. This will not recompose when [header] changes
                NamePickerItem(name) {
                    list.value = list.value + it
                }
            }
        }

        Divider()
        Text(text = "sdalkd;a$a")

//        Header2(header.value) { header.value = it }
        // LazyColumn is the Compose version of a RecyclerView.
        // The lambda passed to items() is similar to a RecyclerView.ViewHolder.

    }
}

/**
 * Display a single name the user can click.
 */
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun NamePickerItem(
    name: String,
//    onClicked: (String) -> Unit,
    onDoubleClicked: (String) -> Unit
) {
    Text(
        name,
        Modifier.clickable { onDoubleClicked(name) }
//            .combinedClickable(onClick = { onClicked(name) },
//                onDoubleClick = { onDoubleClicked(name) })
    )
}

@Composable
fun TestContent() {//无问题
    val scrollState = rememberScrollState()
    Column(
        modifier = Modifier
            .fillMaxSize()
    ) {
        Header2(scroll = scrollState.value)
        Content(scrollState)
    }
}

@Composable
fun Header2(header: String, onNameClicked: (String) -> Unit) {
    Text(
        header,
        style = MaterialTheme.typography.h5,
        modifier = Modifier.clickable(onClick = { onNameClicked(header + 1) })
    )
}

@Composable
fun TestContent2() {//有问题
    val scrollState = rememberScrollState()
    Column(
        modifier = Modifier
            .fillMaxSize()
    ) {
        Header2(scroll = scrollState.value)
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .weight(1f)
                .background(Color.White)
                .verticalScroll(scrollState)
        ) {
            for (i in 0 until 500) {
                Text(text = "scroll content")
            }
        }
    }
}

@Composable
fun TestContent3() {//无问题
    val scrollState = rememberScrollState()
    Column(
        modifier = Modifier
            .fillMaxSize()
    ) {
        Header(scroll = { scrollState.value })
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .weight(1f)
                .background(Color.White)
                .verticalScroll(scrollState)
        ) {
            for (i in 0 until 500) {
                Text(text = "scroll content")
            }
        }
    }
}

@Composable
fun Header(scroll: () -> Int) {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(150.dp)
            .background(Color.Gray)
    ) {
        Text(
            modifier = Modifier.align(Alignment.Center),
            text = "scroll = ${scroll()}",
            fontSize = 17.sp
        )
    }
}

@Composable
fun Header2(scroll: Int) {
    Box(
        modifier = Modifier
            .fillMaxWidth()
            .height(150.dp)
            .background(Color.Gray)
    ) {
        Text(
            modifier = Modifier.align(Alignment.Center),
            text = "scroll = ${scroll}",
            fontSize = 17.sp
        )
    }
}

@Composable
fun ColumnScope.Content(scrollState: ScrollState) {
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .weight(1f)
            .background(Color.White)
            .verticalScroll(scrollState)
    ) {
        for (i in 0 until 500) {
            Text(text = "scroll content")
        }
    }
}

